package com.coder.rental.controller;

import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWTPayload;
import com.coder.rental.entity.Permission;
import com.coder.rental.entity.User;
import com.coder.rental.security.CustomerAuthenticationException;
import com.coder.rental.service.IUserService;
import com.coder.rental.utils.JwtUtils;
import com.coder.rental.utils.RedisUtils;
import com.coder.rental.utils.Result;
import com.coder.rental.utils.RouteTreeUtils;
import com.coder.rental.vo.RouteVO;
import com.coder.rental.vo.TokenVO;
import com.coder.rental.vo.UserInfoVO;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * 编写刷新token处理
 */
@RestController
@RequestMapping("/rental/auth/")
public class AuthController {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private IUserService iUserService;

    /**
     * 刷新token
     * @param request
     * @return
     */
    @PostMapping("refresh")
    public Result reflashToken(HttpServletRequest request){
        //获取token
        String token = request.getHeader("token");
        if (StrUtil.isEmpty(token)){
            token = request.getParameter("token");
        }
        //拿到授权:从SecurityContextHolder上下文中获取Authentication
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        //从token中获取用户名,如果用户名匹配的话,就新生成token
        String username = JwtUtils.parseToken(token).getClaim("username").toString();
        String newToken = "";
        if (StrUtil.equals(username,userDetails.getUsername())){
            HashMap<String, Object> map = new HashMap<>();
            map.put("username",userDetails.getUsername());
            newToken = JwtUtils.createToken(map);
        }else {
            throw new CustomerAuthenticationException("token数据异常");
        }
        //获取token的过期时间
        NumberWithFormat claim = (NumberWithFormat)JwtUtils.parseToken(newToken).getClaim(JWTPayload.EXPIRES_AT);
        DateTime dateTime = (DateTime) claim.convert(DateTime.class, claim);
        long expireTime = dateTime.getTime();
        //创建一个tokenVo的对象,将新生成的token和过期时间存入
        TokenVO tokenVO = new TokenVO();
        tokenVO.setToken(newToken).setExpireTime(expireTime);
        //清除原有的token
        redisUtils.del("token:token");
        long nowTime = DateTime.now().getTime();
        //将新的token存入redis
        redisUtils.set("token:token",newToken,(expireTime-nowTime)/1000);

        return Result.success(tokenVO).setMessage("刷新token成功");
    }

    /**
     * 获取当前用户的信息:登录成功需要返回的用户数据
     *
     * 该接口不需要参数，通过SecurityContextHolder上下文获取认证信息。
     * 如果认证信息存在，则根据用户ID查询用户角色，并将用户基本信息和角色信息封装成UserInfoVo返回。
     * 如果认证信息不存在，则返回失败结果，提示认证信息为空。
     *
     * @return Result 包含用户信息的Result对象，如果获取失败则包含错误信息
     */
    @GetMapping("/info")
    public Result getUserInfo(){
        //从securityContextHolder上下文获取认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication==null){
            return Result.fail().setMessage("认证信息为空");
        }
        User user = (User) authentication.getPrincipal();
//        Object[] array = user.getPermissionList().stream().filter(Objects::nonNull)
//                .map(Permission::getPermissionCode).toArray();
        List<String> list = iUserService.selectRoleName(user.getId());
        //填充到用户信息视图对象
        UserInfoVO userInfoVO = new UserInfoVO(user.getId(),user.getUsername()
                ,user.getAvatar(),user.getNickname(),list.toArray());
        return Result.success(userInfoVO).setMessage("获取用户信息成功");
    }

    @GetMapping("/menuList")
    public Result getMenuList(){
        //获取当前用户信息
        //从securityContextHolder上下文获取认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication==null){
            return Result.fail().setMessage("认证信息为空");
        }
        User user = (User) authentication.getPrincipal();

        //获取用户的权限列表
        List<Permission> permissionList = user.getPermissionList();
        //获取用户的菜单列表
        //sys_permission表中的pid/permission_type为2的数据不需要生成菜单,移除掉
        permissionList.removeIf(permission -> Objects.equals(permission.getPermissionType(),2));
//            permissionList.removeIf(permission -> Objects.equals(permission.getPermissionType(),2));
//            permissionList.removeIf(permission -> Objects.equals(permission.getPermissionType(),2));

        List<RouteVO> routeVOList = RouteTreeUtils.buildRouteTree(permissionList, 0);

        return Result.success(routeVOList).setMessage("获取菜单列表成功");
    }






}
